#include "at24c02.h"
#include "myiic.h"
#include "systick.h"
#include "at24c02.h"
#include "myiic.h"
#include <rtthread.h>

#define AT24C02_ADDR  0x57   // A2 A1 A0 都上拉时，器件地址为 0x57


void i2c3_init(_myiic_t *iic)
{
    rcu_periph_clock_enable(RCU_GPIOA);
    rcu_periph_clock_enable(RCU_GPIOC);

    gpio_init(IIC_SCL_GPIO_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, IIC_SCL_GPIO_PIN);
    gpio_init(IIC_SDA_GPIO_PORT, GPIO_MODE_OUT_OD, GPIO_OSPEED_50MHZ, IIC_SDA_GPIO_PIN);
}

/**
 * @brief 写 1 字节数据到 AT24C02
 * @param iic     模拟 IIC 结构体指针
 * @param addr    EEPROM 内部地址（0~255）
 * @param data    要写入的数据
 * @retval 0 成功，1 失败
 */
uint8_t at24c02_write_byte(_myiic_t *iic, uint8_t addr, uint8_t data)
{
    iic_start(iic);
    iic_send_byte(iic, AT24C02_ADDR << 1 | 0);  // 写操作
    if (iic_wait_ack(iic)) return 1;

    iic_send_byte(iic, addr);                   // 地址
    if (iic_wait_ack(iic)) return 1;

    iic_send_byte(iic, data);                   // 数据
    if (iic_wait_ack(iic)) return 1;

    iic_stop(iic);
    return 0;
}

/**
 * @brief 从 AT24C02 读取 1 字节数据
 * @param iic     模拟 IIC 结构体指针
 * @param addr    EEPROM 内部地址（0~255）
 * @param pdata   读取的数据指针
 * @retval 0 成功，1 失败
 */
uint8_t at24c02_read_byte(_myiic_t *iic, uint8_t addr, uint8_t *pdata)
{
    iic_start(iic);
    iic_send_byte(iic, AT24C02_ADDR << 1 | 0);  // 写操作：先写地址
    if (iic_wait_ack(iic)) return 1;

    iic_send_byte(iic, addr);
    if (iic_wait_ack(iic)) return 1;

    iic_start(iic);                             // 重新起始
    iic_send_byte(iic, AT24C02_ADDR << 1 | 1);  // 读操作
    if (iic_wait_ack(iic)) return 1;

    *pdata = iic_read_byte(iic, 0);             // NACK 结束
    iic_stop(iic);
    return 0;
}

_myiic_t at24c02_iic = {
    .sclport = IIC_SCL_GPIO_PORT,
    .sdaport = IIC_SDA_GPIO_PORT,
    .sclpin  = IIC_SCL_GPIO_PIN,
    .sdapin  = IIC_SDA_GPIO_PIN,
};

void eeprom_test(void)
{
    uint8_t val;

    rt_kprintf("EEPROM Test Start...\n");

    // 写入0xAA到0x10
    if (at24c02_write_byte(&at24c02_iic, 0x00, 0x11) == 0)
    {
        rt_kprintf("Write success\n");
    }
    else
    {
        rt_kprintf("Write fail\n");
    }

    // 延时一会儿
    rt_thread_mdelay(100);

    // 读取回来
    if (at24c02_read_byte(&at24c02_iic, 0x00, &val) == 0)
    {
        rt_kprintf("Read success: 0x%02X\n", val);
    }
    else
    {
        rt_kprintf("Read fail\n");
    }
}
MSH_CMD_EXPORT(eeprom_test, test AT24C02 read and write);
